package com.appspot.abcensys.client;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.logging.Logger;

import com.appspot.abcensys.shared.Les;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextArea;

/**
 * AfwezigheidMelden
 * 
 * @author Hugo Zonderland
 */
public class AfwezigheidMelden {

	// AbcensysService
	private AbcensysServiceAsync service = (AbcensysServiceAsync) GWT.create(AbcensysService.class);

	// FlexTable
	private FlexTable flxTableHeader, flxTable;

	// CheckBox
	private CheckBox afmelden;

	// ListBox
	private ListBox lstCategorie;

	// TextArea
	private TextArea txtToelichting;

	// Row counter
	int row;

	// ArrayList<CheckBox>
	private ArrayList<CheckBox> chkbxList = new ArrayList<CheckBox>();

	// Logger
	private static final Logger log = Logger.getLogger(AfwezigheidMelden.class.getName());

	/**
	 * Constructor
	 */
	public AfwezigheidMelden() {

		Abcensys.setLoadingImage(true);

		// Row init
		row = 0;

		// FlexTable aanmaken
		flxTableHeader = new FlexTable();
		flxTableHeader.setCellPadding(0);
		flxTableHeader.setCellSpacing(3);
		flxTableHeader.setWidth("900px");
		flxTableHeader.setStyleName("datatable");

		// Link widget
		HTML linkWidget = new HTML("Je bent nu hier: Abcensys &raquo; Afwezigheid melden");
		linkWidget.setStyleName("lblLink");
		flxTableHeader.setWidget(row, 0, linkWidget);
		row++;

		// Image
		Image imgAfwezigheidMelden = new Image();
		imgAfwezigheidMelden.setAltText("Afwezigheid melden");
		imgAfwezigheidMelden.setUrl("style/icon/user_delete.png");

		// Pagina header
		HTML h1 = new HTML("<h1> " + imgAfwezigheidMelden.toString() + " Afwezigheid melden</h1>");
		flxTableHeader.setWidget(row, 0, h1);

		// Row resetten
		row = 0;

		// Gewone table aanmaken en plaatsen
		flxTable = new FlexTable();
		flxTable.setCellPadding(0);
		flxTable.setCellSpacing(3);
		flxTable.setWidth("900px");
		flxTable.setStyleName("datatable");

		service.getLesRooster(new AsyncCallback<TreeMap<Les, Boolean>>() {

			public void onFailure(Throwable caught) {
				Window.alert("Er ging iets fout tijdens het ophalen van de gegevens. Probeer het later nog een keer.");
				log.info("Service failure -> getLesRooster -> " + caught.getMessage());
			}

			@SuppressWarnings("deprecation")
			public void onSuccess(TreeMap<Les, Boolean> lessen) {

				// Wanneer er geen lesrooster kan worden opgehaald melding
				// plaatsen
				if (lessen != null && lessen.size() == 0) {
					flxTable.setWidget(row, 0, new Label("Er zijn momenteel geen lessen waar je afwezig voor kan melden."));
				} else {

					// init
					String initLesdatum = null, curLesdatum;

					// iterators setten
					Set<Entry<Les, Boolean>> set = lessen.entrySet();
					Iterator<Entry<Les, Boolean>> i = set.iterator();

					while (i.hasNext()) {

						// Entry setten
						Entry<Les, Boolean> me = i.next();

						// Les setten
						Les les = me.getKey();

						// bepalen of de student al afwezig is voor deze les
						Boolean afwezig = me.getValue();

						// bepalen of er een table header nodig is
						curLesdatum = les.getLesDatum();
						if (!curLesdatum.equals(initLesdatum)) {
							initLesdatum = les.getLesDatum();
							this.getTableHeader(initLesdatum);
						}

						row++;

						// overhevelen in Strings
						String van = les.getStartTijd();
						String tot = les.getEindTijd();
						String activiteit = les.getVakCode();
						String docent = les.maakDocentString();
						String lokaal = les.maakLokaalString();
						String lesDatum[] = les.getLesDatum().split("-");
						String newTot[] = tot.split(":");

						// Controle datum instellen
						Date dLes = new Date();
						dLes.setYear(Integer.parseInt(lesDatum[2].substring(2)) + 100);
						dLes.setMonth(Integer.parseInt(lesDatum[1]));
						dLes.setDate(Integer.parseInt(lesDatum[0]));
						dLes.setHours(Integer.parseInt(newTot[0]));
						dLes.setMinutes(Integer.parseInt(newTot[1]));

						// Huidige datum
						Date dNu = new Date();

						// afmelden checkbox plaatsen
						afmelden = new CheckBox();
						afmelden.setFormValue(les.getIdAsString());
						afmelden.setValue(afwezig);
						// TODO: Moet aangepast worden
						afmelden.setEnabled(!dLes.after(dNu));
						afmelden.addClickHandler(new ClickHandler() {
							public void onClick(ClickEvent event) {
								for (final CheckBox box : chkbxList) {
									if (event.getSource().equals(box)) {
										if (box.isEnabled() && !box.getValue()) {
											service.verwijderAfwezigheidByLesIdAndGebruiker(box.getFormValue(), new AsyncCallback<Boolean>() {
												public void onFailure(Throwable caught) {
													Window.alert("Er ging iets mis met het verwijderen van deze afwezigheidsregistratie.");
													log.info("Service failure -> verwijderAfwezigheidByLesIdAndGebruiker(" + box.getFormValue() + ") -> " + caught.getMessage());
												}

												public void onSuccess(Boolean result) {
													if (!result) {
														Window.alert("De afwezigheidsregistratie kon niet worden verwijderd. Probeer het later opnieuw.");
														return;
													}
													Window.alert("De afwezigheidsregistratie is verwijderd!");
													// Pagina vernieuwen
													new AfwezigheidMelden();
												}
											});
										}
									}
								}
							}
						});
						// Toevoegen aan de ArrayList
						chkbxList.add(afmelden);

						// objecten op de FlexTable plaatsen
						flxTable.setWidget(row, 0, new Label(van));
						flxTable.setWidget(row, 1, new Label(tot));
						flxTable.setWidget(row, 2, new Label(activiteit));
						flxTable.setWidget(row, 3, new Label(docent));
						flxTable.setWidget(row, 4, new Label(lokaal));
						flxTable.setWidget(row, 5, afmelden);

						row++;
					}

					row++;

					// Hier toelichting + categorie + submitbutton (+ events)
					Label lblCategorie = new Label("Waarom afwezig:");

					// ListBox aanmaken
					lstCategorie = new ListBox();
					lstCategorie.addItem("Selecteer een categorie");
					lstCategorie.addItem("Overmacht");
					lstCategorie.addItem("Ziekte");
					lstCategorie.addItem("Overig");

					// ListBox + Label plaatsen
					flxTable.setWidget(row, 0, lblCategorie);
					flxTable.setWidget(row, 1, lstCategorie);

					row++;

					// Toelichting label + textarea.
					Label lblToelichting = new Label("Toelichting");
					txtToelichting = new TextArea();

					// objecten op FlexTable plaatsen
					flxTable.setWidget(row, 0, lblToelichting);
					flxTable.setWidget(row, 1, txtToelichting);

					row++;

					// Button image
					Image imgSubmit = new Image();
					imgSubmit.setAltText("Afwezig melden");
					imgSubmit.setUrl("style/icon/tick.png");

					// Submitbutton + event.
					Button btnSubmit = new Button();
					btnSubmit.setHTML("Afwezig melden " + imgSubmit.toString());
					btnSubmit.addClickHandler(new ClickHandler() {
						public void onClick(ClickEvent event) {

							// Geselecteerde lessen
							final ArrayList<String> lessen = new ArrayList<String>();
							// Categorie
							final String categorie = lstCategorie.getValue(lstCategorie.getSelectedIndex());
							// Toelichting
							final String toelichting = txtToelichting.getValue();

							// Afgemelde lessen bepalen
							for (CheckBox chkbox : chkbxList) {
								if (chkbox.isEnabled() && chkbox.getValue()) {
									lessen.add(chkbox.getFormValue());
								}
							}

							if (lessen != null && !lessen.isEmpty()) {
								if (!categorie.equals("Selecteer een categorie")) {
									if (toelichting.length() < 1000) {
										service.addAfwezigheid(lessen, categorie, toelichting, new AsyncCallback<Boolean>() {
											public void onFailure(Throwable caught) {
												Window.alert("Er ging iets mis bij het opslaan van de registratie.");
												log.info("Service failure -> addAfwezigheid(" + lessen + ", " + categorie + ", " + toelichting + ") -> " + caught.getMessage());
											}

											public void onSuccess(Boolean result) {
												if (result) {
													Window.alert("Je bent succes vol afwezig gemeld voor de les.");
													// Pagina vernieuwen
													new AfwezigheidMelden();
												} else {
													Window.alert("Het opslaan is niet gelukt!");
												}
											}
										});
									} else {
										Window.alert("Toelichting bevat te veel tekens, zorg dat dit er minder dan 1000 zijn.");
									}
								} else {
									Window.alert("Er is geen afwezigheids categorie geselecteerd");
								}
							} else {
								Window.alert("Er zijn geen lessen geselecteerd om afwezig voor te melden.");
							}

						}
					});
					flxTable.setWidget(row, 0, btnSubmit);
				}
				// Header plaatsen
				RootPanel.get("content").add(flxTableHeader);

				// Data plaatsen
				RootPanel.get("content").add(flxTable);

				Abcensys.setLoadingImage(false);
			}

			/**
			 * Maakt een table header met daarin de dag, van, tot, activiteit,
			 * docent, locaal en de mogelijkheid tot afmelden
			 * 
			 * @param String
			 *            met daarin de datum van de les
			 */
			@SuppressWarnings("deprecation")
			private void getTableHeader(String datum) {
				// Datum splitten
				String newDatum[] = datum.split("-");

				// Date setten
				Date d = new Date();
				d.setYear(Integer.parseInt(newDatum[2].substring(2)) + 100);
				d.setMonth(Integer.parseInt(newDatum[1]) - 1);
				d.setDate(Integer.parseInt(newDatum[0]));

				// Label aanmaken
				String dag = getDagNaam(d);

				Label h1Dag = new Label(dag);
				h1Dag.setStyleName("afwezigmeldenDagtop");
				flxTable.setWidget(row, 0, h1Dag);

				row++;

				// Van
				Label lblVan = new Label("Van");
				lblVan.setStyleName("tableheader");

				// Tot
				Label lblTot = new Label("Tot");
				lblTot.setStyleName("tableheader");

				// Activiteit
				Label lblActiviteit = new Label("Activiteit");
				lblActiviteit.setStyleName("tableheader");

				// Docent
				Label lblDocent = new Label("Docent");
				lblDocent.setStyleName("tableheader");

				// Lokaal
				Label lblLokaal = new Label("Lokaal");
				lblLokaal.setStyleName("tableheader");

				// Afwezigmelden
				Label lblAfwezigmelden = new Label("Afwezig melden");
				lblAfwezigmelden.setStyleName("tableheader");

				// Elementen plaatsen
				flxTable.setWidget(row, 0, lblVan);
				flxTable.setWidget(row, 1, lblTot);
				flxTable.setWidget(row, 2, lblActiviteit);
				flxTable.setWidget(row, 3, lblDocent);
				flxTable.setWidget(row, 4, lblLokaal);
				flxTable.setWidget(row, 5, lblAfwezigmelden);
			}
		});
	}

	@SuppressWarnings("deprecation")
	private String getDagNaam(Date d) {
		switch (d.getDay()) {
		case 0:
			return "Zondag";
		case 1:
			return "Maandag";
		case 2:
			return "Dinsdag";
		case 3:
			return "Woensdag";
		case 4:
			return "Donderdag";
		case 5:
			return "Vrijdag";
		case 6:
			return "Zaterdag";
		default:
			return "";
		}
	}
}
